using System.Runtime.InteropServices;

namespace AFEParserWPF.Models;

/// <summary>
/// AFE (Atmosphere Fatal Error) 数据结构
/// </summary>

/// <summary>
/// AFE 版本的魔数常量
/// </summary>
public static class AFEConstants
{
    public const uint ATMOSPHERE_REBOOT_TO_FATAL_MAGIC = 0x32454641;    // "AFE2"
    public const uint ATMOSPHERE_REBOOT_TO_FATAL_MAGIC_1 = 0x31454641;  // "AFE1"
    public const uint ATMOSPHERE_REBOOT_TO_FATAL_MAGIC_0 = 0x30454641;  // "AFE0"

    public const int AMS_FATAL_ERROR_MAX_STACKTRACE = 0x20;
    public const int AMS_FATAL_ERROR_MAX_STACKDUMP = 0x100;
    public const int AMS_FATAL_ERROR_TLS_SIZE = 0x100;
}

/// <summary>
/// AFE2 - Atmosphere 致命错误信息（最新版本，包含 TLS 转储）
/// </summary>
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct AtmosphereFatalErrorCtx
{
    public uint Magic;
    public uint ErrorDesc;
    public ulong TitleId;
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
    public ulong[] Gprs;
    public ulong Pc;
    public ulong ModuleBase;
    public uint Pstate;
    public uint Afsr0;
    public uint Afsr1;
    public uint Esr;
    public ulong Far;
    public ulong ReportIdentifier;
    public ulong StackTraceSize;
    public ulong StackDumpSize;
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x20)]
    public ulong[] StackTrace;
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x100)]
    public byte[] StackDump;
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x100)]
    public byte[] Tls;
}

/// <summary>
/// AFE1 - Atmosphere 致命错误信息版本1（不包含 TLS 转储）
/// </summary>
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct AtmosphereFatalErrorCtx1
{
    public uint Magic;
    public uint ErrorDesc;
    public ulong TitleId;
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
    public ulong[] Gprs;
    public ulong Pc;
    public ulong ModuleBase;
    public uint Pstate;
    public uint Afsr0;
    public uint Afsr1;
    public uint Esr;
    public ulong Far;
    public ulong ReportIdentifier;
    public ulong StackTraceSize;
    public ulong StackDumpSize;
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x20)]
    public ulong[] StackTrace;
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x100)]
    public byte[] StackDump;
}

/// <summary>
/// AFE0 - Atmosphere 致命错误信息版本0（数据最少，无模块基地址）
/// </summary>
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct AtmosphereFatalErrorCtx0
{
    public uint Magic;
    public uint ErrorDesc;
    public ulong TitleId;
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
    public ulong[] Gprs;
    public ulong Pc;
    public ulong Padding;
    public uint Pstate;
    public uint Afsr0;
    public uint Afsr1;
    public uint Esr;
    public ulong Far;
    public ulong ReportIdentifier;
}

/// <summary>
/// 用于识别 AFE 版本的枚举
/// </summary>
public enum AFEVersion
{
    Unknown = 0,
    AFE0 = 1,
    AFE1 = 2,
    AFE2 = 3
}
